#include "../include/memoryPool.h"

namespace memoryPool
{
    MemoryPool::MemoryPool(size_t BlockSize) : BlockSize_(BlockSize),SlotSize_(0),firstBlock_(nullptr),curSlot_(nullptr),freeList_(nullptr),lastSlot_(nullptr) {}
    MemoryPool:: ~MemoryPool()
    {
        //把连续的block删除
        Slot * cur = firstBlock_;
        while(cur)
        {
            Slot * next =cur->next;
            // 转化为void指针，因为operator delete默认返回参数为void* ，而cur可能不是void* 类型，故需要强转
            operator delete(reinterpret_cast<void*>(cur));
            cur=next;
        }
    }

    void MemoryPool::init(size_t size)
    {
        assert(size>0);
        SlotSize_=size;
        firstBlock_=nullptr;
        curSlot_=nullptr;
        freeList_.store(nullptr,std::memory_order_relaxed);
        lastSlot_=nullptr;
    }

    // 实现无锁入队操作
    bool MemoryPool::pushFreeList(Slot * slot)
    {
        while(true){
            // 获取当前头结点
            Slot* oldHead = freeList_.load(std::memory_order_relaxed);
            slot->next.store(oldHead,std::memory_order_relaxed);
            // 尝试将新结点设置为头结点  
            /*成功时：std::memory_order_release，确保本线程中之前的所有内存操作（如 slot->next 的修改）对其他线程可见。失败时：std::memory_order_relaxed，无额外同步开销，直接重试。*/
            //相当于“发布”新节点的数据，确保后续其他线程读取链表时能看到正确状态。
            if(freeList_.compare_exchange_weak(oldHead,slot,std::memory_order_release,std::memory_order_relaxed))
            {
                return true;
            }
            // CAS失败则重试
        }
    }
    
    // 实现无锁出队操作
    Slot* MemoryPool::popFreeList(){
        while(true){
            Slot* oldHead =freeList_.load(std::memory_order_relaxed);
            if(oldHead == nullptr){
                return nullptr;  //队列为空
            }

            // 获取下一个结点
            Slot * newHead = oldHead->next.load(std::memory_order_relaxed);

            // 尝试更新头结点
            // 相当于“获取”其他线程已发布的数据，确保取出的节点及其 next 指针是最新的。
            if(freeList_.compare_exchange_weak(oldHead,newHead,std::memory_order_acquire,std::memory_order_relaxed))
            {
                return oldHead;
            }
            // CAS 失败则重试
        }
    }

    void* MemoryPool::allocate()
    {   
         // 优先使用空闲链表中的内存槽
         Slot * slot =popFreeList();
         if(slot != nullptr){
            return slot;
         }

         // 如果空闲链表为空，则分配新的内存
         std::lock_guard<std::mutex>lock(mutexForBlock_);
         if(curSlot_>=lastSlot_){
            allocateNewBlock();
         }

         Slot * result =curSlot_;
         curSlot_ =reinterpret_cast<Slot*>(reinterpret_cast<char*>(curSlot_)+SlotSize_);
         return result;
    }

    void MemoryPool::deallocate(void* ptr)
    {
        if(!ptr) return;
        Slot * slot = static_cast<Slot*>(ptr);
        pushFreeList(slot);
    }

    void MemoryPool::allocateNewBlock()
    {
        //头插法插入新的内存块
        void* newBlock =operator new(BlockSize_);
        reinterpret_cast<Slot*>(newBlock)->next=firstBlock_;
        firstBlock_=reinterpret_cast<Slot*>(newBlock);

        char * body =reinterpret_cast<char*>(newBlock) +sizeof(Slot*);
        //计算对齐需要填充内存的大小
        size_t paddingSize = padPointer(body,SlotSize_);
        curSlot_=reinterpret_cast<Slot*>(body+paddingSize);

        // 超过该标记位置，则说明该内存块已无内存槽可用，需向系统申请新的内存块
        lastSlot_ =reinterpret_cast<Slot*>(reinterpret_cast<size_t>(newBlock)+BlockSize_-SlotSize_+1);
        freeList_=nullptr;
    }

    size_t MemoryPool::padPointer(char*p,size_t align)
    {
        // align 是槽的大小
        return (align-reinterpret_cast<size_t>(p))% align;
    }

    void HashBucket::initMemoryPool()
    {
        for(int i=0;i<MEMORY_POOL_NUM;i++)
        {
            getMemoryPoll(i).init((i+1)*SLOT_BASE_SIZE);
        }
    }

    //单例模式
    MemoryPool& HashBucket::getMemoryPoll(int index)
    {
        static MemoryPool memoryPool[MEMORY_POOL_NUM];
        return memoryPool[index];
    }

}